package com.katesoft.scale4j.rttp.spring.postprocessor;

import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.log.Logger;
import com.katesoft.scale4j.rttp.client.IClusterInstanceAware;
import com.katesoft.scale4j.rttp.hibernate.SpringHazelcastBridge;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * injects hazelcast instance for those beans, that implements {@link IClusterInstanceAware}
 * interface.
 * 
 * @author kate2007
 */
public class ClusterInstanceAwarePostProcessor implements BeanFactoryPostProcessor {
   private Logger logger = LogFactory.getLogger(getClass());
   private SpringHazelcastBridge hazelcastBridge;

   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
      String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
      for (String name : beanDefinitionNames) {
         Class<?> type = beanFactory.getType(name);
         if (IClusterInstanceAware.class.isAssignableFrom(type)) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
            MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
            mutablePropertyValues.addPropertyValue("clusterInstance",
                     hazelcastBridge.getHazelcastInstance());
            logger.info("injected cluster instance %s into %s bean using %s",
                     hazelcastBridge.getHazelcastInstance(), name,
                     mutablePropertyValues.getPropertyValue("clusterInstance"));
         }
      }
   }

   @Required
   @Autowired
   public void setHazelcastBridge(SpringHazelcastBridge hazelcastBridge) {
      this.hazelcastBridge = hazelcastBridge;
   }
}
